<template>
  <el-form label-width="120px" ref="formRef" :model="skuInfo" :rules="rules">
    <el-form-item label="SPU名称">
      <span>{{ spu.spuName }}</span>
    </el-form-item>
    <el-form-item label="SKU名称" prop="skuName">
      <el-input placeholder="SKU名称" v-model="skuInfo.skuName"></el-input>
    </el-form-item>
    <el-form-item label="价格(元)" prop="price">
      <el-input
        placeholder="请输入价格"
        type="number"
        v-model="skuInfo.price"></el-input>
    </el-form-item>
    <el-form-item label="重量(千克)" prop="weight">
      <el-input
        placeholder="请输入重量"
        type="number"
        v-model="skuInfo.weight"></el-input>
    </el-form-item>
    <el-form-item label="规格描述" prop="skuDesc">
      <el-input
        placeholder="规格描述"
        type="textarea"
        rows="4"
        v-model="skuInfo.skuDesc"></el-input>
    </el-form-item>
    <el-form-item label="平台属性" prop="skuAttrValueList">
      <el-form-item
        :label="attr.attrName"
        v-for="attr in AttrsList"
        :key="attr.id">
        <el-select
          placeholder="请选择"
          v-model="attr.valueId"
          @change="formRef?.clearValidate(['skuAttrValueList'])">
          <el-option
            :value="value.id!"
            :label="value.valueName"
            v-for="value in attr.attrValueList"></el-option>
        </el-select>
      </el-form-item>
    </el-form-item>
    <el-form-item label="销售属性" prop="skuSaleAttrValueList">
      <el-form-item
        :label="attr.saleAttrName"
        v-for="attr in SpuSaleAttrList"
        :key="attr.id">
        <el-select
          placeholder="请选择"
          v-model="attr.valueId"
          @change="formRef?.clearValidate(['skuSaleAttrValueList'])">
          <el-option
            :value="value.id!"
            :label="value.saleAttrValueName"
            v-for="value in attr.spuSaleAttrValueList"></el-option>
        </el-select>
      </el-form-item>
    </el-form-item>
    <el-form-item label="图片列表" prop="skuImageList">
      <el-table border :data="SpuImageList" @selection-change="selectImageList">
        <el-table-column type="selection" width="55px"></el-table-column>
        <el-table-column label="图片">
          <template v-slot="{ row }">
            <el-image
              :src="row.imgUrl"
              style="width: 100px; height: 100px"></el-image>
          </template>
        </el-table-column>
        <el-table-column label="名称" prop="imgName"></el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row }">
            <el-tag v-if="row.imgUrl === skuInfo.skuDefaultImg">默认</el-tag>
            <el-button
              v-else
              type="primary"
              :disabled="!selectedImageList.includes(row)"
              @click="setDefault(row)">
              设置为默认
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-form-item>
    <el-form-item prop="skuDefaultImg"></el-form-item>
    <el-form-item>
      <el-button type="primary" @click="save">保存</el-button>
      <el-button @click="emit('setShowStatus', ShowStatus.SPU_LIST)">
        取消
      </el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import type {
  SpuImageListModel,
  spuImageModel,
  spuModel,
  SpuSaleAttrListModel,
} from "@/api/product/model/spuModel";
import { GetAttrsListApi } from "@/api/product/attr";
import categoryStore from "@/stores/category";
import { storeToRefs } from "pinia";
import type { AttrListModel } from "@/api/product/model/attrsModel";
import type {
  SkuAttrValueListModel,
  SkuModel,
  SkuSaleAttrValueListModel,
} from "@/api/product/model/skuModel";
import { ElMessage, type FormInstance, type FormRules } from "element-plus";
import { saveSkuInfoApi } from "@/api/product/sku";

export default defineComponent({
  name: "SkuForm",
});
</script>

<script setup lang="ts">
import { ShowStatus } from "../types";
import { onMounted, reactive, ref } from "vue";
import { getSpuImageListApi, getSpuSaleAttrListApi } from "@/api/product/Spu";

// 声明定义自定义事件, 返回的是分发事件的函数
const emit = defineEmits<{
  (e: "setShowStatus", value: ShowStatus): void;
}>();

// 接收父组件传过来的spu
const props = defineProps<{
  spu: spuModel;
}>();

const { category1Id, category2Id, category3Id } = storeToRefs(categoryStore());

// 定义数据- spu图片列表
const SpuImageList = ref<SpuImageListModel>([]);
// 平台属性列表
const AttrsList = ref<AttrListModel>([]);
// spu销售属性列表
const SpuSaleAttrList = ref<SpuSaleAttrListModel>([]);
// 初始化请求
onMounted(async () => {
  const p1 = getSpuImageListApi(props.spu.id!);
  const p2 = GetAttrsListApi({
    category1Id: category1Id.value!,
    category2Id: category2Id.value!,
    category3Id: category3Id.value!,
  });
  const p3 = getSpuSaleAttrListApi(props.spu.id!);
  const result = await Promise.all([p1, p2, p3]);

  SpuImageList.value = result[0];
  AttrsList.value = result[1];
  SpuSaleAttrList.value = result[2];
});

// 定义一个发保存请求需要的参数对象
const skuInfo = reactive<SkuModel>({
  // props中读取
  category3Id: props.spu.category3Id!,
  // category3Id: category3Id.value!,
  spuId: props.spu.id!,
  tmId: props.spu.tmId!,
  // v-model收集
  skuName: "",
  skuDesc: "",
  price: 0,
  weight: 0,
  // 其它
  skuDefaultImg: "", // 默认图片url
  skuAttrValueList: [],
  skuSaleAttrValueList: [],
  skuImageList: [],
  isSale: 1,
});

// 所有选中的spu图片的数组
const selectedImageList = ref<SpuImageListModel>([]);

/*
spu图片选中发生改变: 全选/全不选, 选中/不选中某个
values: 所有选中的spu图片的数组
*/
const selectImageList = (values: SpuImageListModel) => {
  selectedImageList.value = values;
};

/* **请求保存 start** */
const save = async () => {
  await formRef.value?.validate();
  // alert("准备发添加sku的请求");
  skuInfo.skuAttrValueList = AttrsList.value.reduce((pre, item) => {
    // 如果item中有valueId, 创建一个目标对象, 保存到pre
    if (item.valueId) {
      pre.push({
        attrId: item.id!,
        valueId: item.valueId!,
      });
    }
    return pre;
  }, [] as SkuAttrValueListModel); // 一定指定初始空数组的类型是SkuAttrValueListModel
  skuInfo.skuSaleAttrValueList = SpuSaleAttrList.value.reduce((pre, item) => {
    // 如果item中有valueId, 创建一个目标对象, 保存到pre
    if (item.valueId) {
      pre.push({
        saleAttrValueId: item.valueId!,
      });
    }
    return pre;
  }, [] as SkuSaleAttrValueListModel);
  skuInfo.skuImageList = selectedImageList.value.map((item) => ({
    imgName: item.imgName,
    imgUrl: item.imgUrl,
    spuImgId: item.id!, // 当前Spu图片的id
    isDefault: item.imgUrl === skuInfo.skuDefaultImg ? "1" : "0", // 默认为"1", 非默认为"0"
  }));

  // 2. 发送保存sku的请求, 提交skuInfo
  await saveSkuInfoApi(skuInfo);

  // 3. 请求成功后: 提示 / 跳转到spu列表界面
  ElMessage.success("保存SKU成功啦!");
  emit("setShowStatus", ShowStatus.SPU_LIST);
};
/* **请求保存 end** */

/* **表单校验 start** */
const formRef = ref<FormInstance>();
const rules: FormRules = {
  skuName: [{ required: true, message: "名称是必须的" }],
  skuDesc: [{ required: true, message: "描述是必须的" }],
  price: [
    {
      validator: (rule, value, callback) => {
        // 要求价格大于0
        if (+value > 0) {
          callback(); // 校验通过
        } else {
          callback("价格必须大于0"); // 校验不通过, 并指定要显示的文本
        }
      },
    },
  ],
  weight: [
    {
      validator: (rule, value, callback) => {
        // 要求价格大于0
        if (+value > 0) {
          callback(); // 校验通过
        } else {
          callback("重量必须大于0"); // 校验不通过, 并指定要显示的文本
        }
      },
    },
  ],
  skuDefaultImg: [{ required: true, message: "默认图片是必须的" }],
  skuAttrValueList: [
    {
      validator: (rule, value, callback) => {
        // 判断attrList中是否至少有一个attr是有valueId的
        if (AttrsList.value.some((item) => item.valueId)) {
          callback();
        } else {
          callback("至少选择一个平台属性");
        }
      },
    },
  ],
  skuSaleAttrValueList: [
    {
      validator: (rule, value, callback) => {
        // 判断spuSaleAttrList中是否至少有一个attr是有valueId的
        if (SpuSaleAttrList.value.some((item) => item.valueId)) {
          callback();
        } else {
          callback("至少选择一个销售属性");
        }
      },
    },
  ],
  skuImageList: [
    {
      validator: (rule, value, callback) => {
        // selectedImageList的长度大于0
        if (selectedImageList.value.length > 0) {
          callback(); // 校验通过
        } else {
          callback("至少选择一张图片"); // 校验不通过, 并指定要显示的文本
        }
      },
    },
  ],
};
/* **表单校验 end** */

const setDefault = (row: spuImageModel) => {
  // 保存默认图片
  skuInfo.skuDefaultImg = row.imgUrl;
  // 手动清除对应的校验错误
  formRef.value?.clearValidate(["skuDefaultImg"]);
};
</script>

<style scoped lang="scss"></style>
